Bug 524110 - Gdk should not assume reparenting WMs when retrieving window
authorCody Russell <bratsche@gnome.org>
Sun, 25 May 2008 23:14:39 +0000 (23:14 +0000)
committerCody Russell <bratsche@src.gnome.org>
Sun, 25 May 2008 23:14:39 +0000 (23:14 +0000)
2008-05-25  Cody Russell  <bratsche@gnome.org>

        Bug 524110 - Gdk should not assume reparenting WMs when retrieving
        window frame extents

        * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents):
        Use _NET_FRAME_EXTENTS, if available. Patch by Danny Baumann.

svn path=/trunk/; revision=20164

ChangeLog
gdk/x11/gdkwindow-x11.c

index d3f123f573f99ce80db33492201dd9b4d5c1bc3e..efb803ff29ef5b3eae66191b13339a24bbb09a49 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-05-25  Cody Russell  <bratsche@gnome.org>
+
+       Bug 524110 - Gdk should not assume reparenting WMs when retrieving
+       window frame extents
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents):
+       Use _NET_FRAME_EXTENTS, if available.  Patch by Danny Baumann.
+
 2008-05-25  Cody Russell  <bratsche@gnome.org>
 
        Bug 522269 - Evince windows sometimes incorrectly unmaximized,
index ddecb24c042b932cd4dd8541f1da26bdfb14cfc0..d5d7160ca05d4301ee3a689db5e725ea0754625f 100644 (file)
@@ -3391,6 +3391,7 @@ gdk_window_get_frame_extents (GdkWindow    *window,
   gint i;
   guint ww, wh, wb, wd;
   gint wx, wy;
+  gboolean got_frame_extents = FALSE;
   
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (rect != NULL);
@@ -3416,14 +3417,59 @@ gdk_window_get_frame_extents (GdkWindow    *window,
   if (GDK_WINDOW_DESTROYED (private))
     return;
 
+  nvroots = 0;
+  vroots = NULL;
+
   gdk_error_trap_push();
   
-  /* use NETWM_VIRTUAL_ROOTS if available */
   display = gdk_drawable_get_display (window);
-  root = GDK_WINDOW_XROOTWIN (window);
+  xwindow = GDK_WINDOW_XID (window);
 
-  nvroots = 0;
-  vroots = NULL;
+  /* first try: use _NET_FRAME_EXTENTS */
+  if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
+                         gdk_x11_get_xatom_by_name_for_display (display,
+                                                                "_NET_FRAME_EXTENTS"),
+                         0, G_MAXLONG, False, XA_CARDINAL, &type_return,
+                         &format_return, &nitems_return, &bytes_after_return,
+                         &data)
+      == Success)
+    {
+      if ((type_return == XA_CARDINAL) && (format_return == 32) &&
+         (nitems_return == 4) && (data))
+        {
+         guint32 *ldata = (guint32 *) data;
+         got_frame_extents = TRUE;
+
+         /* try to get the real client window geometry */
+         if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow,
+                           &root, &wx, &wy, &ww, &wh, &wb, &wd))
+           {
+             rect->x = wx;
+             rect->y = wy;
+             rect->width = ww;
+             rect->height = wh;
+           }
+
+         /* _NET_FRAME_EXTENTS format is left, right, top, bottom */
+         rect->x -= ldata[0];
+         rect->y -= ldata[2];
+         rect->width += ldata[0] + ldata[1];
+         rect->height += ldata[2] + ldata[3];
+       }
+
+      if (data)
+       XFree (data);
+    }
+
+  if (got_frame_extents)
+    goto out;
+
+  /* no frame extents property available, which means we either have a WM that
+     is not EWMH compliant or is broken - try fallback and walk up the window
+     tree to get our window's parent which hopefully is the window frame */
+
+  /* use NETWM_VIRTUAL_ROOTS if available */
+  root = GDK_WINDOW_XROOTWIN (window);
 
   if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), root,
                          gdk_x11_get_xatom_by_name_for_display (display, 
@@ -3449,7 +3495,7 @@ gdk_window_get_frame_extents (GdkWindow    *window,
       if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xwindow,
                       &root, &xparent,
                       &children, &nchildren))
-       goto fail;
+       goto out;
       
       if (children)
        XFree (children);
@@ -3475,7 +3521,7 @@ gdk_window_get_frame_extents (GdkWindow    *window,
       rect->height = wh;
     }
 
fail:
out:
   if (vroots)
     XFree (vroots);